import { PackageConfig } from "@ap/types/config";
import { getPackageJson } from "@ap/util/packageJson";
import { Box3Get, get, nGet, prodUrl } from "@ap/util/request";
import {
  showErrorMessage,
  showInformationMessage,
  showProgress,
} from "@ap/util/vscode/message";
import { transformDao3Resources } from "./transformDao3Resources";
import { arenaErrorMsg } from "@ap/util/vscode/errorMsg";

export async function getGroupProject(mapId: string) {
  const requestOptions = {
    url: "engine/map-group-project?mapId=" + mapId + "&mode=edit",
  };
  /**
   * 发送请求并等待响应。
   */
  const response = await Box3Get(requestOptions, "地图工程数据组");
  /**
   * 检查响应是否成功，如果不成功则返回错误消息。
   */
  if (!response || response.code !== 200) {
    showErrorMessage(`获取地图数据失败: ${response.msg}`);
    return;
  }
  return response;
}

export const STATIC_URL = "https://static.dao3.fun/block/";

async function fetchAndTransformResource(
  response: Record<string, any>,
  assetType: "audioAssets" | "pictureAssets",
  mapId: string,
  resourceName: string,
) {
  try {
    const requestOptions = { url: `${STATIC_URL}${response.data[assetType]}` };
    const resourceResponse = await get<Record<string, any>>(
      requestOptions,
      resourceName,
    );
    if (!resourceResponse) {
      showErrorMessage(`获取${resourceName}数据失败`);
      return null;
    }
    return resourceResponse;
  } catch (error) {
    console.error(`获取${resourceName}时发生错误:`, error);
    showErrorMessage(`获取${resourceName}数据失败`);
    return null;
  }
}

export async function getResourceAll() {
  const packageJson = await getPackageJson<PackageConfig>("map");
  if (packageJson) {
    const mapId = packageJson.id;
    if (mapId) {
      return await getDao3Resources(mapId);
    }
  }
  return "失败";
}

interface Item {
  modelName: any;
  name: string;
  size: number;
  previewImage: string;
}

export async function getDao3Resources(mapId: string) {
  let offset = 0;
  let totalCount = 0;
  const modelAssets: Record<string, any> = {};
  await showProgress("获取地图所有模型文件", async (progress) => {
    do {
      const requestOptions = {
        url:
          prodUrl +
          `models/v2?modelType=2&creativeMode=1&mapId=${mapId}&limit=100&containerMode=edit&offset=${offset}`,
      };

      /**
       * 发送请求并等待响应。
       */
      const response = await nGet<Record<string, any>>(requestOptions);
      /**
       * 检查响应是否成功，如果不成功则返回错误消息。
       */
      if (!response || response.code !== 200) {
        showErrorMessage(`获取地图模型失败: ${response?.code}`);
        return;
      }

      for (const value of Object.values<Item>(response.data.rows)) {
        modelAssets[`mesh/${value.modelName}.vb`] = {};
      }

      totalCount = response.data.count;
      offset += totalCount >= 100 ? 100 : totalCount;
      progress.report({
        message: "进度：" + offset.toString() + "/" + totalCount.toString(),
        increment: ((totalCount >= 100 ? 100 : totalCount) / totalCount) * 100,
      });
    } while (offset < totalCount);
  });

  const response = await getGroupProject(mapId);
  if (!response) {
    showErrorMessage(`获取地图数据失败`);
    return;
  }

  const [audioAsset, pictureAssets] = await Promise.all([
    fetchAndTransformResource(response, "audioAssets", mapId, "地图音频"),
    fetchAndTransformResource(response, "pictureAssets", mapId, "地图图片"),
  ]);
  transformDao3Resources(
    {
      audioAsset,
      pictureAssets,
      modelAssets,
    },
    mapId,
  );
  return {
    audioAsset,
    pictureAssets,
    modelAssets,
  };
}
